package tr.edu.yildiz.dap.appeditor.componentproviders;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.maven.ide.eclipse.MavenPlugin;
import org.maven.ide.eclipse.embedder.ArtifactRef;
import org.maven.ide.eclipse.project.IMavenProjectFacade;
import org.maven.ide.eclipse.project.MavenProjectManager;

import tr.edu.yildiz.dap.appeditor.componentproviders.basic.AbstractComponentProvider;
import tr.edu.yildiz.dap.appeditor.componentproviders.basic.ComponentManager;
import tr.edu.yildiz.dap.appeditor.componentproviders.basic.IComponentProvider;
import tr.edu.yildiz.dap.appeditor.model.AppComponent;
import tr.edu.yildiz.dap.appeditor.model.MavenAppComponent;
import tr.edu.yildiz.dap.appeditor.model.ProjectAppComponent;

public class WorkspaceComponentProvider extends AbstractComponentProvider{


	static Map<String,IMavenProjectFacade> mavenProjectMap = new HashMap<String, IMavenProjectFacade>();
	
	private static String generateKey(IMavenProjectFacade mpFacade){
		return 	generateKey(mpFacade.getArtifactKey().getArtifactId(),
							mpFacade.getArtifactKey().getGroupId(),
							mpFacade.getArtifactKey().getVersion());
	}
	
	private static String generateKey(ArtifactRef artifactRef){
		return 	generateKey(artifactRef.getArtifactId(),artifactRef.getGroupId(),artifactRef.getVersion());
	} 
	
	private static String generateKey(String artifactId,String groupId,String version){
		return 	artifactId 
				+ groupId 
				+ version;
	} 
	
	public WorkspaceComponentProvider(ComponentManager componentProvider) {
		super(componentProvider);
	}
	
	@Override
	public List<AppComponent> listComponents() {
		initProjectList();
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		MavenProjectManager projectManager = MavenPlugin.getDefault().getMavenProjectManager();
		List<AppComponent> list = new ArrayList<AppComponent>();
		for (IProject iProject : projects) {
			ProjectAppComponent appComponent = new ProjectAppComponent();
			IMavenProjectFacade facade = projectManager.getProject(iProject);
			if (facade != null){
				appComponent = (ProjectAppComponent) getComponent(	facade.getArtifactKey().getArtifactId(), 
																	facade.getArtifactKey().getGroupId(), 
																	facade.getArtifactKey().getVersion());
//				initDependencies(appComponent, facade);
				list.add(appComponent);
			}
		}
		
		return list;
	}
	
	@Override
	public AppComponent getComponent(String artifactId, String groupId,
			String version) {
		IMavenProjectFacade facade = mavenProjectMap.get(generateKey(artifactId,groupId,version));
		Set<ArtifactRef> artifacts = facade.getMavenProjectArtifacts();
		
		ProjectAppComponent component = new ProjectAppComponent();
		component.setId(facade.getArtifactKey().getArtifactId());
		component.setGroupId(facade.getArtifactKey().getGroupId());
		component.setVersion(facade.getArtifactKey().getVersion());
		component.setUrlString(getProjectBuildUrl(facade));
		
		Iterator<ArtifactRef> artifact = artifacts.iterator();
		while (artifact.hasNext()) {
			ArtifactRef artifactRef = (ArtifactRef) artifact.next();
			if ((artifactRef.getScope()!= null &&  artifactRef.getScope().equals("provided"))
					|| (artifactRef.getScope()!= null &&  artifactRef.getScope().equals("test")))
				continue;
			getDependencyComponent(component, artifactRef,facade);
		}
		return component;
	}
	
	
	private void initProjectList(){
		mavenProjectMap.clear();
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		MavenProjectManager projectManager = MavenPlugin.getDefault().getMavenProjectManager();
		List<AppComponent> list = new ArrayList<AppComponent>();
		for (IProject iProject : projects) {
			AppComponent appComponent = new ProjectAppComponent();
			IMavenProjectFacade facade = projectManager.getProject(iProject);
			if (facade == null)
				continue;
			mavenProjectMap.put(generateKey(facade), facade);
		}	
	}
	
	private static boolean isWorkspaceDependency(ArtifactRef artifactRef){
		if (mavenProjectMap.containsKey(generateKey(artifactRef)))
			return true;
		return false;
	}
	

	private void initDependencies(ProjectAppComponent projectAppComponent,IMavenProjectFacade facade){
	 	Set<ArtifactRef> artifacts = facade.getMavenProjectArtifacts();
		Iterator<ArtifactRef> artifact = artifacts.iterator();
		while (artifact.hasNext()) {
			ArtifactRef artifactRef = (ArtifactRef) artifact.next();
			if (!artifactRef.getScope().equals("provided"))
				getDependencyComponent(projectAppComponent, artifactRef,facade);
		}
	}
	
	private void getDependencyComponent(ProjectAppComponent projectAppComponent,ArtifactRef artifactRef,IMavenProjectFacade facade){
		AppComponent subComponent = null; 
		if (isWorkspaceDependency(artifactRef)){
			subComponent = getComponent(artifactRef.getArtifactId(),
										artifactRef.getGroupId(),
										artifactRef.getVersion());
		}else {
			subComponent = componentManager.getMavenComponentProvider().getComponent(	artifactRef.getArtifactId(),
																		artifactRef.getGroupId(),
																		artifactRef.getVersion());
			subComponent.setUrlString(getArtifactRepositoryUrl(artifactRef, facade));
		}
		projectAppComponent.getDependencyList().add(subComponent);
	}
	
	private String getProjectBuildUrl(IMavenProjectFacade facade){
		String path;
		try {
			path = facade.getProject().getLocationURI().toURL().toString() + "/target/";
			return path + facade.getArtifactKey().getArtifactId() + "-" + facade.getArtifactKey().getVersion() + ".jar";
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	//TODO : More than one repositories can be defined in pom.xml.
	private String getArtifactRepositoryUrl(ArtifactRef artifactRef,IMavenProjectFacade facade){
		String url = facade.getArtifactRepositoryRefs().iterator().next().getUrl();
		return url + "/" + convertToFolderFormat(artifactRef.getGroupId()) + "/" + artifactRef.getArtifactId() 
		+ "/" + artifactRef.getVersion() + "/" + getJarName(artifactRef);
	} 
	
	private String convertToFolderFormat(String groupId){
		return groupId.replaceAll("\\.", "\\/");
	}
	
	private String getJarName(ArtifactRef artifactRef){
		return artifactRef.getArtifactId() + "-" + artifactRef.getVersion() + ".jar";
	}
	
}
